package com.pktechan.api.service.impl;

import com.pktechan.api.base.BaseMapper;
import com.pktechan.api.base.BaseServiceImpl;
import com.pktechan.api.dao.TradeOrderMapper;
import com.pktechan.api.entity.*;
import com.pktechan.api.enumeration.*;
import com.pktechan.api.exception.CustomException;
import com.pktechan.api.sendMiniMessage.BaseSendMiniMessage;
import com.pktechan.api.sendMiniMessage.SendMiniMessageStrategy;
import com.pktechan.api.sendMiniMessage.bean.DistributorOrderTransferApplyMessage;
import com.pktechan.api.sendMiniMessage.enumration.SendMiniMessageEnum;
import com.pktechan.api.service.*;
import com.pktechan.api.tradeOrderStatus.BaseChangeTradeOrderState;
import com.pktechan.api.tradeOrderStatus.ChangeTradeOrderState;
import com.pktechan.api.utils.DateUtil;
import com.pktechan.api.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.DelayQueue;
import java.util.stream.Collectors;

@Service("tradeOrderService")
@Transactional
public class TradeOrderServiceImpl extends BaseServiceImpl<TradeOrder> implements TradeOrderService {
    private final static Logger logger = LoggerFactory.getLogger(TradeOrderServiceImpl.class);
    @Autowired
    private TradeOrderMapper tradeOrderMapper;

    @Autowired
    private ProductService productService;

    @Autowired
    private ShopCartService shopCartService;

    @Autowired
    private CustAddressService custAddressService;

    @Autowired
    private TradeOrderDetailService tradeOrderDetailService;

    @Autowired
    private WxPayOrderService wxPayOrderService;
    @Autowired
    private CustBaseService custBaseService;
    @Autowired
    private SendMessageService sendMessageService;

    @Autowired
    DelayQueue tradeOrderExpireDelayedQueue;

    /**
     * 由业务类实现
     *
     * @return
     */
    @Override
    public BaseMapper<TradeOrder> getBaseMapper() {
        return tradeOrderMapper;
    }

    /**
     * 产品下订单
     *
     * @param shopCartIdList 购物车ID集合
     * @param custAddressId  收货地址ID
     */
    @Override
    public TradeOrder repurchasePlaceOrder(List<Integer> shopCartIdList, Integer custAddressId, CustBase custBase) {
        if (custBase == null && custBase.getId() == null) {
            throw new CustomException("当前客户未完成注册。");
        }
        //根据购物车id查询对应信息
        List<ShopCartVO> shopCartList = shopCartService.getShopCartByIds(shopCartIdList);
        //获取订单总金额
        BigDecimal totalAmount = shopCartList.stream().map(shopCartVO -> shopCartVO.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
        //根据客户收货地址id获取收货信息
        CustAddress custAddress = custAddressService.getById(custAddressId);
        if (custAddress == null) {
            throw new CustomException("请重新选择地址");
        }
        //保存订单信息
        TradeOrder tradeOrder = saveTradeOrder(custBase, custAddress, totalAmount);
        //保存订单详情信息
        saveTradeOrderDetail(tradeOrder.getId(), shopCartList, custBase);
        //记录操作流水
        ChangeTradeOrderState changeTradeOrderState = BaseChangeTradeOrderState.getChangeContractState(ChangeTradeOrderStatusEnum.PLACE_ORDER);
        changeTradeOrderState.doChange(tradeOrder.getId(), TradeOrderStatusEnum.TO_BE_PAID.getCode(), TradeOrderStatusEnum.TO_BE_PAID.getCode(), custBase.getId(), ChangeTradeOrderStatusEnum.PLACE_ORDER.getName());
        //将订单加入到过期队列中
        setTradeOrderExpireDelay(tradeOrder);
        return tradeOrder;
    }

    /**
     * 获取订单列表及订单详情信息集合
     *
     * @param tradeOrder
     * @return
     */
    @Override
    public List<TradeOrderVO> getTradeOrderList(TradeOrder tradeOrder) {
        List<TradeOrderVO> tradeOrderList = tradeOrderMapper.getTradeOrderList(tradeOrder);
        for (TradeOrderVO tradeOrderVO : tradeOrderList) {
            List<TradeOrderDetailVO> tradeOrderDetailVOList = tradeOrderDetailService.getTradeOrderDetailByOrderId(tradeOrderVO.getId());
            tradeOrderVO.setTradeOrderDetailVOList(tradeOrderDetailVOList);
        }
        return tradeOrderList;
    }

    /**
     * 保存订单
     *
     * @param custBase
     * @param custAddress
     * @param totalAmount
     * @return
     */
    private TradeOrder saveTradeOrder(CustBase custBase, CustAddress custAddress, BigDecimal totalAmount) {
        TradeOrder tradeOrder = new TradeOrder();
        tradeOrder.setCustId(custBase.getId());
        tradeOrder.setBbId(custBase.getBbId());
        tradeOrder.setYyId(custBase.getYyId());
        tradeOrder.setZzId(custBase.getZzId());
        tradeOrder.setContact(custAddress.getContact());
        tradeOrder.setMobile(custAddress.getMobile());
        tradeOrder.setProvince(custAddress.getProvince());
        tradeOrder.setCity(custAddress.getCity());
        tradeOrder.setCounty(custAddress.getCounty());
        tradeOrder.setStreet(custAddress.getStreet());
        tradeOrder.setAddress(custAddress.getAddress());
        tradeOrder.setAmount(totalAmount);
        tradeOrder.setDistributionCenterId(custBase.getDistributionCenterId());
        tradeOrder.setWxPayOutTradeNo(wxPayOrderService.createId());
        tradeOrderMapper.save(tradeOrder);
        return tradeOrder;
    }

    /**
     * 保存订单详情
     *
     * @param tradeOrderId
     * @param shopCartList
     * @return
     */
    private void saveTradeOrderDetail(Integer tradeOrderId, List<ShopCartVO> shopCartList, CustBase custBase) {
        //获取产品信息id结合
        List<Integer> productIdList = shopCartList.stream().map(ShopCartVO::getProductId).collect(Collectors.toList());
        //根据产品id集合查询对应产品信息集合
        List<ProductBaseInfo> productList = productService.getProductByProductIds(productIdList);
        //productId为key,分类为value
        Map<Integer, Integer> productCategoryMap = productList.stream().collect(Collectors.toMap(ProductBaseInfo::getId, ProductBaseInfo::getCategory));
        Map<Integer, Integer> productCloudTicketMap = productList.stream().collect(Collectors.toMap(ProductBaseInfo::getId, ProductBaseInfo::getCloudTicket));

        for (ShopCartVO shopCartVO : shopCartList) {
            TradeOrderDetail tradeOrderDetail = new TradeOrderDetail();
            tradeOrderDetail.setTradeOrderId(tradeOrderId);
            tradeOrderDetail.setAmount(shopCartVO.getAmount());
            tradeOrderDetail.setCustId(shopCartVO.getCustId());
            tradeOrderDetail.setProductId(shopCartVO.getProductId());
            tradeOrderDetail.setCount(shopCartVO.getCount());
            tradeOrderDetail.setPrice(shopCartVO.getPrice());
            tradeOrderDetail.setCount(shopCartVO.getCount());
            tradeOrderDetail.setCloudPoint(shopCartVO.getCloudPoint());
            tradeOrderDetail.setCloudTicket(productCloudTicketMap.get(shopCartVO.getProductId()));
            tradeOrderDetail.setPriceCarriage(shopCartVO.getPriceCarriage());
            Integer category = productCategoryMap.get(shopCartVO.getProductId());
//            20240604 商品规则简单化，且不出现配送商的概念，系统只有唯的配送商888，以下代码注释了
//            if (ProductCategoryEnum.REGISTER_DISTRIBUTOR.getCode().equals(category) && shopCartList.size() > 1) {
//                throw new CustomException("注册配送商请单独购买");
//            }
//            //1、注册成配送商，不需配送，直接完成，佣金规则不变，但积分与运费都由本人获得；
//            //2、配送商复购，不需配送，直接完成，佣金规则不变，但积分与运费都由本人获得；
//            if (ProductCategoryEnum.REGISTER_DISTRIBUTOR.getCode().equals(category) && shopCartList.size() == 1) {
//                //如果购买的为注册配送商，则更新订单的配送商为当前客户自己
//                TradeOrder tradeOrder = new TradeOrder();
//                tradeOrder.setId(tradeOrderId);
//                tradeOrder.setDistributionCenterId(custBase.getId());
//                tradeOrderMapper.update(tradeOrder);
//            }
//20240604 业务种类仅通过商品属性体现，不再表现在订单上。订单业务种类只有一种：下单，默认为10
//            tradeOrderDetail.setBusinessType(BusinessTypeEnum.getBusinessType(custBase.getVipType(), category));
            tradeOrderDetail.setBusinessType(10);
            tradeOrderDetailService.save(tradeOrderDetail);
            //根据购物车ID删除对应信息repurchasePlaceOrder
            shopCartService.deleteById(shopCartVO.getId());
        }
    }

    /**
     * 根据custId和订单状态查询订单
     *
     * @param tradeOrder
     * @return
     */
    @Override
    public List<TradeOrderVO> getTradeOrderListByCustIdAndStatus(TradeOrderVO tradeOrder) {
        List<TradeOrderVO> tradeOrderVOList = tradeOrderMapper.getTradeOrderListByCustIdAndStatus(tradeOrder);
        for (TradeOrderVO tradeOrderVO : tradeOrderVOList) {
            TradeOrderDetailVO detail = tradeOrderDetailService.getOrderDetailById(tradeOrderVO.getId());
            tradeOrderVO.setProductDetail(detail.getProductDetail());
            tradeOrderVO.setCloudPointCount(detail.getCloudPoint());
            tradeOrderVO.setPriceCarriageCount(detail.getPriceCarriage());
        }
        return tradeOrderVOList;
    }

    /**
     * 订单转让
     *
     * @param tradeOrder
     */
    @Override
    public void orderTransfer(TradeOrderVO tradeOrder) {
        //记录操作流水
        logger.debug("订单转让" + "，订单ID：" + tradeOrder.getId() + "，变更前状态：" + TradeOrderStatusEnum.ORDERS_TO_BE_RECEIVED.getName() + "，变更后状态：" + TradeOrderStatusEnum.ORDERS_TO_BE_RECEIVED.getName()
                + "，操作人角色ID：" + tradeOrder.getOldDistributionCenterId() + "，操作说明：" + "订单转让新配送中心ID=" + tradeOrder.getDistributionCenterId() + "原配送中心ID=" + tradeOrder.getOldDistributionCenterId());
        CustBase distributionCustBase = custBaseService.getById(tradeOrder.getDistributionCenterId());
        if (distributionCustBase == null) {
            logger.error("订单ID：" + tradeOrder.getId() + ",转让失败。受让配送商" + tradeOrder.getDistributionCenterId() + "不存在");
            throw new CustomException("配送商不存在");
        }
        if (distributionCustBase != null && !VipTypeEnum.DISTRIBUTOR.getCode().equals(distributionCustBase.getVipType())) {
            logger.error("订单ID：" + tradeOrder.getId() + ",转让失败。受让配送商" + tradeOrder.getDistributionCenterId() + "无配送权限");
            throw new CustomException("受让人无配送权限");
        }

        //记录操作流水
        ChangeTradeOrderState changeTradeOrderState = BaseChangeTradeOrderState.getChangeContractState(ChangeTradeOrderStatusEnum.TRANSFER_ORDER);
        changeTradeOrderState.doChange(tradeOrder.getId(), TradeOrderStatusEnum.ORDERS_TO_BE_RECEIVED.getCode(), TradeOrderStatusEnum.ORDERS_TO_BE_RECEIVED.getCode(), tradeOrder.getOldDistributionCenterId(), ChangeTradeOrderStatusEnum.TRANSFER_ORDER.getName());

        //更改配送中心id
        TradeOrder order = new TradeOrder();
        order.setId(tradeOrder.getId());
        order.setDistributionCenterId(tradeOrder.getDistributionCenterId());
        tradeOrderMapper.update(order);
        logger.debug("订单转让通知--------------");
        //订单转让通知
        CustBase oldCustBase = custBaseService.getById(tradeOrder.getOldDistributionCenterId());
        String name = null;
        if (oldCustBase.getName() != null) {
            name = oldCustBase.getName();
        } else {
            name = oldCustBase.getNickname();
        }
        DistributorOrderTransferApplyMessage distributorOrderTransferApplyMessage = sendMessageService.getDistributorOrderTransferApplyMessage(tradeOrder.getId());
        //转出人姓名
        distributorOrderTransferApplyMessage.setDistributionCenter(name);
        //转入人openId
        distributorOrderTransferApplyMessage.setOpenId(distributionCustBase.getOpenId());
        SendMiniMessageStrategy sendMiniMessageStrategy = BaseSendMiniMessage.getSendMiniMessage(SendMiniMessageEnum.DISTRIBUTOR_ORDER_TRANSFER_APPLY);
        sendMiniMessageStrategy.sendMiniMessageToActiveMq(distributorOrderTransferApplyMessage);

    }

    /**
     * 直接下单
     *
     * @param productId
     * @param custAddressId
     * @param count
     * @param custBase
     */
    @Override
    public TradeOrder placeAnOrder(Integer productId, Integer custAddressId, Integer count, CustBase custBase) {
        //获取产品详情
        ProductBaseInfo productBaseInfo = productService.getById(productId);
        //根据产品数量计算总金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        totalAmount = productBaseInfo.getPrice().multiply(new BigDecimal(count.toString()));
        //根据客户收货地址id获取收货信息
        CustAddress custAddress = custAddressService.getById(custAddressId);
        TradeOrder tradeOrder = saveTradeOrder(custBase, custAddress, totalAmount);
        //保存订单详情
        addTradeOrderDetail(tradeOrder.getId(), productBaseInfo, count, custBase);
        //记录操作流水
        ChangeTradeOrderState changeTradeOrderState = BaseChangeTradeOrderState.getChangeContractState(ChangeTradeOrderStatusEnum.PLACE_ORDER);
        changeTradeOrderState.doChange(tradeOrder.getId(), TradeOrderStatusEnum.TO_BE_PAID.getCode(), TradeOrderStatusEnum.TO_BE_PAID.getCode(), custBase.getId(), ChangeTradeOrderStatusEnum.PLACE_ORDER.getName());
        //将订单加入到过期队列中
        setTradeOrderExpireDelay(tradeOrder);
        return tradeOrder;
    }

    /**
     * 下单保存订单详情
     *
     * @param tradeOrderId
     * @param productBaseInfo
     * @param count
     */
    private void addTradeOrderDetail(Integer tradeOrderId, ProductBaseInfo productBaseInfo, Integer count, CustBase custBase) {
        //根据产品数量计算总金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        totalAmount = productBaseInfo.getPrice().multiply(new BigDecimal(count.toString()));
        TradeOrderDetail tradeOrderDetail = new TradeOrderDetail();
        tradeOrderDetail.setTradeOrderId(tradeOrderId);
        tradeOrderDetail.setAmount(totalAmount);
        tradeOrderDetail.setCustId(custBase.getId());
        tradeOrderDetail.setProductId(productBaseInfo.getId());
        tradeOrderDetail.setCount(count);
        tradeOrderDetail.setPrice(productBaseInfo.getPrice());
        tradeOrderDetail.setCloudPoint(productBaseInfo.getCloudPoint());
        tradeOrderDetail.setCloudTicket(productBaseInfo.getCloudTicket());
        tradeOrderDetail.setPriceCarriage(productBaseInfo.getPriceCarriage());
        //20240604 业务种类仅通过商品属性体现，不再表现在订单上。订单业务种类只有一种：下单，默认为10
//        tradeOrderDetail.setBusinessType(BusinessTypeEnum.getBusinessType(custBase.getVipType(), productBaseInfo.getCategory()));
        tradeOrderDetail.setBusinessType(10);
        tradeOrderDetailService.save(tradeOrderDetail);
    }

    /**
     * 根据custId查询订单状态数量
     *
     * @param tradeOrder
     */
    @Override
    public List<TradeOrderStatusVO> getTradeOrderCountByCustId(TradeOrderVO tradeOrder) {
        return tradeOrderMapper.getTradeOrderCountByCustId(tradeOrder);
    }

    /**
     * 根据微信支付订单号查询订单信息
     *
     * @param wxPayOutTradeNo
     * @return
     */
    @Override
    public TradeOrder getByWxPayOutTradeNo(String wxPayOutTradeNo) {
        return tradeOrderMapper.getByWxPayOutTradeNo(wxPayOutTradeNo);
    }

    /**
     * 获取直接推荐人下的订单集合
     */
    @Override
    public List<TradeOrderVO> getTradeOrderVOByCustId(Integer custId) {
        List<TradeOrderVO> tradeOrderVOList = tradeOrderMapper.getTradeOrderVOByCustId(custId);
        for (TradeOrderVO tradeOrderVO : tradeOrderVOList) {
            List<TradeOrderDetailVO> tradeOrderDetailVOList = tradeOrderDetailService.getTradeOrderDetailByOrderId(tradeOrderVO.getId());
            tradeOrderVO.setTradeOrderDetailVOList(tradeOrderDetailVOList);
        }
        return tradeOrderVOList;
    }

    /**
     * 获取间接推荐人下的订单集合
     */
    @Override
    public List<TradeOrderVO> getTradeOrderVOByYyId(Integer yyId) {
        List<TradeOrderVO> tradeOrderVOList = tradeOrderMapper.getTradeOrderVOByYyId(yyId);
        for (TradeOrderVO tradeOrderVO : tradeOrderVOList) {
            List<TradeOrderDetailVO> tradeOrderDetailVOList = tradeOrderDetailService.getTradeOrderDetailByOrderId(tradeOrderVO.getId());
            tradeOrderVO.setTradeOrderDetailVOList(tradeOrderDetailVOList);
        }
        return tradeOrderVOList;
    }

    /**
     * 订单过期延时队列
     *
     * @param tradeOrder
     */
    @Override
    public void setTradeOrderExpireDelay(TradeOrder tradeOrder) {
        logger.debug("将此订单加入到订单过期延时队列，订单ID：" + tradeOrder.getId());
        TradeOrderExpireDelayed tradeOrderExpireDelayed = new TradeOrderExpireDelayed();
        tradeOrderExpireDelayed.setTradeOrderId(tradeOrder.getId());
        tradeOrderExpireDelayed.setExpirationTime(DateUtil.addMinute(new Date(), 30));
        tradeOrderExpireDelayedQueue.add(tradeOrderExpireDelayed);
    }

    /**
     * 获取订单过期列表
     *
     * @return
     */
    @Override
    public List<TradeOrderExpireDelayed> getTradeOrderExpireList() {
        return tradeOrderMapper.getTradeOrderExpireList();
    }

    /**
     * 删除延时队列
     *
     * @param tradeOrder
     */
    @Override
    public void deleteTradeOrderExpireDelay(TradeOrder tradeOrder) {
        logger.debug("将此订单从延时队列中删除，订单ID：" + tradeOrder.getId());
        TradeOrderExpireDelayed tradeOrderExpireDelayed = new TradeOrderExpireDelayed();
        tradeOrderExpireDelayed.setTradeOrderId(tradeOrder.getId());
        tradeOrderExpireDelayedQueue.remove(tradeOrderExpireDelayed);
    }

    @Override
    public Integer getMeSendingOrderCnt(Integer custId) {
        return tradeOrderMapper.getMeSendingOrderCnt(custId);
    }
}
